<?php
final class XDB extends XObject{
	private static $instance = null;
	private $drivers = array();
	private $loaded = false;
	
	private function __construct() {
	
	}

	/**
	 * @return XDB
	 */	
	static function singleton() {
		if (!self::$instance) {
			self::$instance = new self;
		}
		return self::$instance;
	}
	
	/**
	 * @return XDBDriver
	 */	
	public function driver($driverName = null){
		if(!$this->loaded){
			$this->load();
		}
		if(isset($this->drivers[$driverName])){
			return $this->drivers[$driverName];
		}
		//get driver by model class
		if(class_exists($driverName, false)
			&& is_subclass_of($driverName, "XARRecord")){
			$record = new $driverName();
			return $record->dao()->driver();
		}
		if(!is_null($driverName)
			&& !isset($this->drivers[$driverName])){
			throw new XORMException("Database driver {$driverName} configuration does not exist");
			return null;
		}
		if(isset($this->drivers['default'])){
			return $this->drivers['default'];
		}
		return x_array_head($this->drivers);
	}
			
	public function load(){
		$config = XConfig::singleton()->get("project.db.driver");
		if(is_null($config) || empty($config)){
			throw new XORMException("Database drivers configuration does not exist");
		}
		foreach($config as $key => $value){
			$name = $key;
			if(isset($value['name'])){
				$name = $value['name'];
			}
			$class = "";
			if(isset($value['class'])){
				$class = $value['class'];
			}else{
				$class = x_class_name($name);
				$class = "X{$class}Driver";
			}
			if(!XClassLoader::loader($class)->isSubclassOf('XDBDriver')){
				throw new XException("class {$class} must implement interface XDBDriver.");
			}
			$driver = XFactory::singleton()->get($class, null, array($name, $value));
			if(XClassLoader::loader($class)->implementsInterface('XDBXAResource')
				&& $driver->supportsXA()){
				$driver = new XDBXAProxy(XDBXA::singleton(), $driver);
			}
			$this->drivers[$name] = $driver;
		}
		$this->loaded = true;
		return true;
	}
}
?>